﻿using SHomeWorkshop.LunarConcept.ModifingManager;
using SHomeWorkshop.LunarConcept.Widgets;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SHomeWorkshop.LunarConcept.Controls
{
    class UserStyleListItem : ListBoxItem
    {
        public UserStyleListItem()
        {
            this.Margin = new Thickness(2);
            this.widgetClassName = "<未知部件>";
            this.tbWidgetStyleFileName.Text = $"<未知部件：未知样式>";
            this.Padding = new Thickness(4);

            this.Content = this.tbWidgetStyleFileName;
            this.MouseDoubleClick += UserStyleListItem_MouseDoubleClick;
            this.PreviewMouseLeftButtonDown += UserStyleListItem_PreviewMouseLeftButtonDown;
        }

        private void UserStyleListItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 1)
            {
                bool isCtrl = false;
                KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
                KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
                if ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0)
                {
                    isCtrl = true;
                }

                var tagText = "Insert" + this.widgetClassName.Replace("Widget", "");
                if (tagText.EndsWith("Line") == false)
                    tagText += "Line";

                switch (this.widgetStyle.WidgetClassName)
                {
                    case "BezierLineWidget":
                    case "BrackedWidget":
                    case "EllipseWidget":
                    case "PolyLineWidget":
                    case "RectangleWidget":
                    case "RhombWidget":
                    case "StraitLineWidget":
                    case "TrangleWidget":
                        {
                            Globals.MainWindow.PrepareToInsertLineWidget(tagText, isCtrl);
                            break;
                        }
                }

                Globals.MainWindow.EditorManager.FormatBrush = new FormatBrush()
                {
                    DefaultWidgetStyle = new WidgetStyle(widgetStyle.WidgetClassName)
                    {
                        IsShadowVisible = widgetStyle.IsShadowVisible,
                        WidgetOpacity = widgetStyle.WidgetOpacity,
                        WidgetBackColor = widgetStyle.WidgetBackColor,
                        WidgetLineColor = widgetStyle.WidgetLineColor,
                        WidgetLineWidth = widgetStyle.WidgetLineWidth,
                        WidgetForeColor = widgetStyle.WidgetForeColor,
                        WidgetPadding = widgetStyle.WidgetPadding,
                        WidgetOutBorderType = widgetStyle.WidgetOutBorderType,
                        WidgetForm = widgetStyle.WidgetForm,
                        TriangleForm = widgetStyle.TriangleForm,
                    },
                    OnlyFormatOnceTime = !isCtrl,
                };

            }
        }

        private void UserStyleListItem_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (widgetStyle == null) return;
            var manager = Globals.MainWindow.EditorManager;
            if (manager == null)
            {
                MessageBox.Show("　　发生意外，未找到页面管理器！", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            var pe = manager.GetMainSelectedPageEditor();
            if (pe == null)
            {
                MessageBox.Show("　　发生意外，未找到页面！", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            manager.FormatBrush = new FormatBrush() { DefaultWidgetStyle = widgetStyle, OnlyFormatOnceTime = true, };

            var info = new ModifingInfo();
            info.ModifingDescription = "应用部件样式";
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            var widgets = pe.GetSelectedWidgetsList();
            foreach (var widget in widgets)
            {
                var aw = widget as Widgets.ArrowLineWidget;
                if (aw != null)
                {
                    aw.FormatSelf(ref mi, ref info);
                    continue;
                }

                var cw = widget as Widgets.ContentWidget;
                if (cw != null)
                {
                    cw.FormatSelf(ref mi, ref info);
                    continue;
                }

                var sw = widget as Widgets.ShapeWidget;
                if (sw != null)
                {
                    sw.FormatSelf(ref mi, ref info);
                    continue;
                }
            }

            manager.RegisterModifingItem(mi);

            if (manager.FormatBrush.OnlyFormatOnceTime)
            {
                pe.RaiseWidgetFormated(widgets);
            }
        }

        public UserStyleListItem(WidgetStyle style, string styleName)
        {
            this.widgetStyle = style;
            this.widgetStyleFileName = styleName;

            this.Margin = new Thickness(2);
            this.Padding = new Thickness(4);
            this.Content = this.tbWidgetStyleFileName;
            this.MouseDoubleClick += UserStyleListItem_MouseDoubleClick;
            this.PreviewMouseLeftButtonDown += UserStyleListItem_PreviewMouseLeftButtonDown;

            if (style == null)
            {
                this.widgetClassName = "<未知部件>";
                this.tbWidgetStyleFileName.Text = "<未知部件：未知样式>";
            }
            else
            {
                var dp = new DockPanel()
                {
                    LastChildFill = true,
                };

                var sampleCanvas = new Canvas()
                {
                    Height = 32,
                    Width = 32,
                };

                dp.Children.Add(sampleCanvas);

                DockPanel.SetDock(sampleCanvas, Dock.Left);

                tbWidgetStyleFileName.VerticalAlignment = VerticalAlignment.Center;
                tbWidgetStyleFileName.TextWrapping = TextWrapping.Wrap;
                DrawSample(ref sampleCanvas, style);

                this.Content = dp;
                dp.Children.Add(tbWidgetStyleFileName);

                this.widgetStyle = style;
                this.widgetClassName = style.WidgetClassName;
                if (styleName.ToLower().EndsWith(".txt"))
                    styleName = styleName.Substring(0, styleName.Length - 4);
                this.widgetStyleFileName = styleName;
                this.tbWidgetStyleFileName.Text = this.WidgetClassName + " : " + styleName;
            }
        }

        public UserStyleListItem(string pathOfUserStyleFile)
        {
            this.Padding = new Thickness(4);
            this.Margin = new Thickness(2);

            this.MouseDoubleClick += UserStyleListItem_MouseDoubleClick;
            this.PreviewMouseLeftButtonDown += UserStyleListItem_PreviewMouseLeftButtonDown;

            try
            {
                using (StreamReader sr = new StreamReader(pathOfUserStyleFile))
                {
                    var xmlText = sr.ReadToEnd();

                    if (string.IsNullOrWhiteSpace(xmlText) == false)
                    {
                        var style = WidgetStyle.FromXML(xmlText);
                        if (style == null)
                        {
                            this.Content = this.tbWidgetStyleFileName;

                            this.widgetClassName = "<未知部件>";
                            this.tbWidgetStyleFileName.Text = "<未知部件：未知样式>";
                        }
                        else
                        {
                            var dp = new DockPanel()
                            {
                                LastChildFill = true,
                            };

                            var sampleCanvas = new Canvas()
                            {
                                Height = 32,
                                Width = 32,
                            };

                            dp.Children.Add(sampleCanvas);

                            DockPanel.SetDock(sampleCanvas, Dock.Left);

                            tbWidgetStyleFileName.VerticalAlignment = VerticalAlignment.Center;
                            tbWidgetStyleFileName.TextWrapping = TextWrapping.Wrap;
                            DrawSample(ref sampleCanvas, style);
                            dp.Children.Add(tbWidgetStyleFileName);

                            this.Content = dp;

                            this.widgetStyle = style;
                            this.widgetClassName = style.WidgetClassName;
                            var styleName = new FileInfo(pathOfUserStyleFile).Name;
                            if (styleName.ToLower().EndsWith(".txt"))
                                styleName = styleName.Substring(0, styleName.Length - 4);
                            this.widgetStyleFileName = styleName;
                            this.tbWidgetStyleFileName.Text = this.WidgetClassName + " : " + styleName;
                        }
                    }
                }
            }
            catch
            {
                this.widgetClassName = "<未知部件>";
                this.tbWidgetStyleFileName.Text = "<未知部件：未知样式>";
                return;
            }
        }

        private void UserStyleListItem_MouseLeftButtonDown2(object sender, MouseButtonEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void DrawSample(ref Canvas canvas, WidgetStyle style)
        {
            switch (style.WidgetClassName)
            {
                case "BezierLineWidget":
                    {
                        var path = new System.Windows.Shapes.Path();
                        var pg = new PathGeometry();
                        var pf = new PathFigure();
                        var bs = new BezierSegment();

                        pf.StartPoint = new Point(10, 10);

                        bs.Point1 = new Point(22, 10);
                        bs.Point2 = new Point(22, 22);
                        bs.Point3 = new Point(10, 22);

                        path.Stroke = style.WidgetLineColor;
                        path.Fill = style.WidgetBackColor;
                        path.StrokeThickness = style.WidgetLineWidth;
                        path.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        path.Opacity = style.WidgetOpacity;

                        pf.Segments.Add(bs);
                        pg.Figures.Add(pf);
                        path.Data = pg;

                        canvas.Children.Add(path);
                        break;
                    }
                case "BracketWidget":
                    {
                        var path = new System.Windows.Shapes.Path();
                        var pg = new PathGeometry();
                        var pf = new PathFigure();
                        var bs1 = new BezierSegment();

                        pf.StartPoint = new Point(10, 10);

                        bs1.Point1 = new Point(22, 10);
                        bs1.Point2 = new Point(10, 16);
                        bs1.Point3 = new Point(22, 16);

                        var bs2 = new BezierSegment();

                        bs2.Point1 = new Point(10, 16);
                        bs2.Point2 = new Point(22, 22);
                        bs2.Point3 = new Point(10, 22);

                        path.Stroke = style.WidgetLineColor;
                        path.Fill = style.WidgetBackColor;
                        path.StrokeThickness = style.WidgetLineWidth;
                        path.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        path.Opacity = style.WidgetOpacity;

                        pf.Segments.Add(bs1);
                        pf.Segments.Add(bs2);
                        pg.Figures.Add(pf);
                        path.Data = pg;

                        canvas.Children.Add(path);
                        break;
                    }
                case "EllipseWidget":
                    {
                        var e = new System.Windows.Shapes.Ellipse()
                        {
                            Height = 24,
                            Width = 24,
                        };

                        Canvas.SetLeft(e, 4);
                        Canvas.SetTop(e, 4);

                        e.Stroke = style.WidgetLineColor;
                        e.Fill = style.WidgetBackColor;
                        e.StrokeThickness = style.WidgetLineWidth;
                        e.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        e.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(e);
                        break;
                    }
                case "GroupWidget":
                    {
                        var r = new System.Windows.Shapes.Rectangle()
                        {
                            Height = 24,
                            Width = 24,
                        };

                        Canvas.SetLeft(r, 4);
                        Canvas.SetTop(r, 4);

                        r.Stroke = style.WidgetLineColor;
                        r.Fill = style.WidgetBackColor;
                        r.StrokeThickness = style.WidgetLineWidth;
                        r.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        r.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(r);
                        break;
                    }
                case "PictureBoxWidget":
                    {
                        var r = new System.Windows.Shapes.Rectangle()
                        {
                            Height = 24,
                            Width = 24,
                        };

                        Canvas.SetLeft(r, 4);
                        Canvas.SetTop(r, 4);

                        r.Stroke = style.WidgetLineColor;
                        r.Fill = style.WidgetBackColor;
                        r.StrokeThickness = style.WidgetLineWidth;
                        r.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        r.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(r);

                        var img = new Image()
                        {
                            Width = 16,
                            Height = 16,
                            Source = new BitmapImage(new Uri("pack://Application:,,,/LunarConcept;component/Images/PictureBox.png")),
                        };

                        Canvas.SetLeft(img, 8);
                        Canvas.SetTop(img, 8);

                        canvas.Children.Add(img);
                        break;
                    }
                case "PolyLineWidget":
                    {
                        var path = new System.Windows.Shapes.Path();
                        var pg = new PathGeometry();
                        var pf = new PathFigure();
                        var ps = new PolyLineSegment();

                        pf.StartPoint = new Point(10, 10);

                        ps.Points = new PointCollection()
                        {
                            new Point(16,10),
                            new Point(16,22),
                            new Point(22,22),
                        };

                        path.Stroke = style.WidgetLineColor;
                        path.Fill = style.WidgetBackColor;
                        path.StrokeThickness = style.WidgetLineWidth;
                        path.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        path.Opacity = style.WidgetOpacity;

                        pf.Segments.Add(ps);
                        pg.Figures.Add(pf);
                        path.Data = pg;

                        canvas.Children.Add(path);
                        break;
                    }
                case "RectangleWidget":
                    {
                        var r = new System.Windows.Shapes.Rectangle()
                        {
                            Height = 24,
                            Width = 24,
                        };

                        Canvas.SetLeft(r, 4);
                        Canvas.SetTop(r, 4);

                        r.Stroke = style.WidgetLineColor;
                        r.Fill = style.WidgetBackColor;
                        r.StrokeThickness = style.WidgetLineWidth;
                        r.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        r.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(r);
                        break;
                    }
                case "RhombWidget":
                    {
                        var path = new System.Windows.Shapes.Path();
                        var pg = new PathGeometry();
                        var pf = new PathFigure();
                        var ps = new PolyLineSegment();

                        pf.StartPoint = new Point(16, 10);

                        ps.Points = new PointCollection()
                        {
                            new Point(22,16),
                            new Point(16,22),
                            new Point(10,16),
                            new Point(16,10),
                        };

                        path.Stroke = style.WidgetLineColor;
                        path.Fill = style.WidgetBackColor;
                        path.StrokeThickness = style.WidgetLineWidth;
                        path.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        path.Opacity = style.WidgetOpacity;

                        pf.Segments.Add(ps);
                        pg.Figures.Add(pf);
                        path.Data = pg;

                        canvas.Children.Add(path);
                        break;
                    }
                case "StraitLineWidget":
                    {
                        var l = new System.Windows.Shapes.Line();

                        l.X1 = l.Y1 = 10;
                        l.X2 = l.Y2 = 22;

                        l.Stroke = style.WidgetLineColor;
                        l.Fill = style.WidgetBackColor;
                        l.StrokeThickness = style.WidgetLineWidth;
                        l.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        l.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(l);
                        break;
                    }
                case "TextAreaWidget":
                    {
                        var bd = new Border()
                        {
                            Width = 22,
                            Height = 22,
                        };

                        var tb = new TextBlock()
                        {
                            Text = "A",
                            VerticalAlignment = VerticalAlignment.Center,
                            HorizontalAlignment = HorizontalAlignment.Center,
                        };
                        bd.Child = tb;

                        bd.BorderThickness = new Thickness(style.WidgetLineWidth);
                        bd.Background = style.WidgetBackColor;
                        bd.BorderBrush = style.WidgetLineColor;
                        bd.Opacity = style.WidgetOpacity;

                        canvas.Children.Add(bd);
                        Canvas.SetTop(bd, 10);
                        Canvas.SetLeft(bd, 10);
                        break;
                    }
                case "TrangleWidget":
                    {
                        var path = new System.Windows.Shapes.Path();
                        var pg = new PathGeometry();
                        var pf = new PathFigure();
                        var ps = new PolyLineSegment();

                        pf.StartPoint = new Point(16, 10);

                        ps.Points = new PointCollection()
                        {
                            new Point(22,22),
                            new Point(10,22),
                            new Point(16,10),
                        };

                        path.Stroke = style.WidgetLineColor;
                        path.Fill = style.WidgetBackColor;
                        path.StrokeThickness = style.WidgetLineWidth;
                        path.StrokeDashArray = LineDashType.GetDashCollection(style.LineDash);
                        path.Opacity = style.WidgetOpacity;

                        pf.Segments.Add(ps);
                        pg.Figures.Add(pf);
                        path.Data = pg;

                        canvas.Children.Add(path);
                        break;
                    }

            }
        }

        private WidgetStyle widgetStyle = null;

        public WidgetStyle WidgetStyle { get { return widgetStyle; } }

        private Border baseBorder = new Border()
        {
            BorderBrush = Brushes.Gold,
            BorderThickness = new Thickness(1),
            Margin = new Thickness(5),
            Padding = new Thickness(2),
        };

        private string widgetClassName;
        public string WidgetClassName
        {
            get
            {
                return Widget.GetWidgetClassLocalName(widgetClassName);
            }
        }

        private TextBlock tbWidgetStyleFileName = new TextBlock()
        {
            TextDecorations = TextDecorations.Underline,
            VerticalAlignment = VerticalAlignment.Center,
        };

        private string widgetStyleFileName = "";

        public string WidgetStyleFileName { get { return widgetStyleFileName; } }
    }
}
